﻿using DependencyAnalysis.Algorithms.SubstringDetection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTests
{
    [TestClass]
    public class SuffixTreeTest
    {
        [TestMethod]
        public void NumberOfNodesIsCorrect()
        {
            var suffixTree = new SuffixTree("book$".ToCharArray());
            var nodeCount = suffixTree.CreateNewNodeNumber();
            Assert.AreEqual(7, nodeCount);
            suffixTree = new SuffixTree("banana$".ToCharArray());
            nodeCount = suffixTree.CreateNewNodeNumber();
            Assert.AreEqual(11, nodeCount);
        }

        [TestMethod]
        public void WhenTreeContainsStringReturnTrue()
        {
            var suffixTree = new SuffixTree("banana$".ToCharArray());
            var contains = suffixTree.Contains("anan".ToCharArray());
            Assert.AreEqual(true, contains);
        }

        [TestMethod]
        public void WhenTreeDoesNotContainsStringReturnFalse()
        {
            var suffixTree = new SuffixTree("Hello world!$".ToCharArray());
            var contains = suffixTree.Contains("anan".ToCharArray());
            Assert.AreEqual(false, contains);
        }

        [TestMethod]
        public void WhenTreeContainsStringThenIndexOfIsCorrect()
        {
            var suffixTree = new SuffixTree("Hello world!$".ToCharArray());
            var index = suffixTree.IndexOf("world".ToCharArray());
            Assert.AreEqual(6, index);
        }

        [TestMethod]
        public void WhenTreeDoesNotContainStringThenIndexOfIsMinusOne()
        {
            var suffixTree = new SuffixTree("BanAna$".ToCharArray());
            var index = suffixTree.IndexOf("world".ToCharArray());
            Assert.AreEqual(-1, index);
        }

        [TestMethod]
        public void WhenNoRepeatitionFoundReturnNull()
        {
            var suffixTree = new SuffixTree("abcdefghijklmnopqrstuvwxyz$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.IsNull(repeatition);
        }

        [TestMethod]
        public void FindRepeatitionsStartingAtIndex0ReturnsCommonSubstringWithLength2()
        {
            var suffixTree = new SuffixTree("FGaFG$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(2, repeatition.Length);
        }

        [TestMethod]
        public void FindRepeatitionsStartingAtIndex0ReturnsCommonSubstringWithCorrectIndices()
        {
            var suffixTree = new SuffixTree("FGaFG$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(0, repeatition.BeginIndices[0]);
            Assert.AreEqual(3, repeatition.BeginIndices[1]);
        }
        
        [TestMethod]
        public void FindRepeatitionsStartingAtIndex3ReturnsCommonSubstringWithLength2()
        {
            var suffixTree = new SuffixTree("123FGaFG$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(2, repeatition.Length);
        }

        [TestMethod]
        public void FindRepeatitionsReturnsCommonSubstringWith2Instances()
        {
            var suffixTree = new SuffixTree("123FGaFG$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(2, repeatition.BeginIndices.Length);
        }

        [TestMethod]
        public void FindRepeatitionsReturnsCommonSubstringWith3Instances()
        {
            var suffixTree = new SuffixTree("123FGaFGdefFGhj$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(3, repeatition.BeginIndices.Length);
        }
        
        [TestMethod]
        public void FindRepeatitionsStartingAtIndex3ReturnsCommonSubstringWithCorrectIndices()
        {
            var suffixTree = new SuffixTree("123FGaFG$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(3, repeatition.BeginIndices[0]);
            Assert.AreEqual(6, repeatition.BeginIndices[1]);
        }
        
        [TestMethod]
        public void FindLongestRepeatitionAmongSmallerRepeatitions()
        {
            var suffixTree = new SuffixTree("abcABCdefABCghiDEFGjklDEFGm$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(4, repeatition.Length);
        }

        [TestMethod]
        public void FindLongestRepeatitionAmongSmallerRepeatitionsWithCorrectindices()
        {
            var suffixTree = new SuffixTree("abcABCdefABCghiDEFGjklDEFGm$".ToCharArray());
            var repeatition = suffixTree.FindLongestRepeatition();
            Assert.AreEqual(15, repeatition.BeginIndices[0]);
            Assert.AreEqual(22, repeatition.BeginIndices[1]);
        }
    }
}
